#include "House.h"

//Complete forward declarations
#include "StaticInstancedModel.h"
#include "GraphicsInterface.h"

House::House()
{
	//Init pointers to NULL
	houseExterior = 0;
}

House::~House()
{
	//Clean up after ourselves. 
	SafeDelete(houseExterior);
}

void House::Init(ID3D11Device* device, unsigned numHousesInScene)
{
	//Alloc memory for model (house)
	houseExterior = new StaticInstancedModel(device, numHousesInScene);

	//Load the model from file
	houseExterior->CreateModelThroughAssimp(device, 
		std::string(HOUSE_MODEL_FILE_PATH), std::string(HOUSE_MODEL_TEXTURE_FILE_PATH),
		true, true, true, false, false); 

	//Set material manually
	Material mat;
	mat.Ambient = XMFLOAT4(0.15f, 0.15f, 0.15f, 1.0f);
	mat.Diffuse = XMFLOAT4(0.35f, 0.35f, 0.35f, 1.0f);
	mat.Specular = XMFLOAT4(0.0f, 0.0f, 0.0f, 64.0f);
	mat.Reflection = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);

	//All submodels have the same material for the time being. 
	houseExterior->SetSubmodelsWithSameMaterial(mat);
}

void House::CreateInstance(XMFLOAT3 position, XMFLOAT3 rotation, XMFLOAT3 scale,
		std::string sceneTransitionKey)
{
	//Create an instance of the model (house). 
	houseExterior->CreateInstance(position, rotation, scale, true);

	//Push the scene to transition on to vector
	scenesKey.push_back(sceneTransitionKey);

	//temp hitbox used to add to vector
	AABB temphit;

	// Create bounding box for each instance
	temphit.CenterW = position;

	XMFLOAT3 temp = houseExterior->GetAABBL().Extents;

	temp.x *= (scale.x*2);
	temp.y *= (scale.y*2);
	temp.z *= (scale.z*2);

	temphit.ExtentsW = temp;
	HitBox.push_back(temphit);
}

AABB House::GetHitBox(unsigned instanceID)
{
	return HitBox[instanceID];
}

void House::AddToBatch(GraphicsInterface* gi)
{
	//Render the house exterior model.
	gi->AddModelToBatch(houseExterior);
}

void House::IsHouseWithinRange(XMFLOAT3 locationOfPlayer, 
		std::string &sceneToTransitionOut, bool &isAHouseInRange)
{
	//Init output - Initially, no house found
	isAHouseInRange = false;
	sceneToTransitionOut = "";

	//Loop through out instances. 
	for (unsigned i = 0; i < houseExterior->ReturnInstanceCount(); i++)
	{
		//Get location of the ith house
		InstanceData* iData = houseExterior->GetInstanceData(i);

		if (GetDistance(iData->Pos, locationOfPlayer) <= HOUSE_TRANSITION_RANGE)
		{
			//Set flag as match has been found. 
			isAHouseInRange = true;

			//Set the string by using the i index to index in to our scenesKey
			sceneToTransitionOut = scenesKey[i];
		}
	}
}

float House::GetDistance(XMFLOAT3 a, XMFLOAT3 b)
{
	//Load float3's in to vectors so we can get the distance. 
	XMVECTOR aVec = XMLoadFloat3(&a);
	XMVECTOR bVec = XMLoadFloat3(&b);
	
	//Vector from a to b
	XMVECTOR toVec = bVec - aVec;

	//Get Lenght
	XMVECTOR len =  XMVector3Length(toVec);
	
	//Store in to a float
	float ret = 0.0f;
	XMStoreFloat(&ret, len);

	//return 
	return ret;
}